home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_053 / uuencode / uudecode.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  4KB  |  226 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)uudecode.c    5.3-1 (Berkeley) 4/10/85";
  3. #endif
  4. /* modified by ajr to use checksums */
  5. /* modified by fnf to use Keith Pyle's suggestion for compatibility */
  6.  
  7. /*
  8.  * uudecode [input]
  9.  *
  10.  * create the specified file, decoding as you go.
  11.  * used with uuencode.
  12.  */
  13. #include <stdio.h>
  14.  
  15. #ifdef unix
  16. #include <pwd.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #endif
  20.  
  21. #define SUMSIZE 64
  22.  
  23. /* single character decode */
  24. #define DEC(c)    (((c) - ' ') & 077)
  25.  
  26. main(argc, argv)
  27. char **argv;
  28. {
  29.     FILE *in, *out;
  30.     int mode;
  31.     char dest[128];
  32.     char buf[80];
  33.  
  34.     /* optional input arg */
  35.     if (argc > 1) {
  36.         if ((in = fopen(argv[1], "r")) == NULL) {
  37.             perror(argv[1]);
  38.             exit(1);
  39.         }
  40.         argv++; argc--;
  41.     } else
  42.         in = stdin;
  43.  
  44.     if (argc != 1) {
  45.         printf("Usage: uudecode [infile]\n");
  46.         exit(2);
  47.     }
  48.  
  49.     /* search for header line */
  50.     for (;;) {
  51.         if (fgets(buf, sizeof buf, in) == NULL) {
  52.             fprintf(stderr, "No begin line\n");
  53.             exit(3);
  54.         }
  55.         if (strncmp(buf, "begin ", 6) == 0)
  56.             break;
  57.     }
  58.     sscanf(buf, "begin %o %s", &mode, dest);
  59.  
  60. #ifdef unix
  61.     /* handle ~user/file format */
  62.     if (dest[0] == '~') {
  63.         char *sl;
  64.         struct passwd *getpwnam();
  65.         char *index();
  66.         struct passwd *user;
  67.         char dnbuf[100];
  68.  
  69.         sl = index(dest, '/');
  70.         if (sl == NULL) {
  71.             fprintf(stderr, "Illegal ~user\n");
  72.             exit(3);
  73.         }
  74.         *sl++ = 0;
  75.         user = getpwnam(dest+1);
  76.         if (user == NULL) {
  77.             fprintf(stderr, "No such user as %s\n", dest);
  78.             exit(4);
  79.         }
  80.         strcpy(dnbuf, user->pw_dir);
  81.         strcat(dnbuf, "/");
  82.         strcat(dnbuf, sl);
  83.         strcpy(dest, dnbuf);
  84.     }
  85. #endif
  86.  
  87.     /* create output file */
  88.     out = fopen(dest, "w");
  89.     if (out == NULL) {
  90.         perror(dest);
  91.         exit(4);
  92.     }
  93. #if (unix || !MANX)
  94.     chmod(dest, mode);
  95. #endif
  96.  
  97.     decode(in, out);
  98.  
  99.     if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
  100.         fprintf(stderr, "No end line\n");
  101.         exit(5);
  102.     }
  103.     exit(0);
  104. }
  105.  
  106. /*
  107.  * copy from in to out, decoding as you go along.
  108.  */
  109. decode(in, out)
  110. FILE *in;
  111. FILE *out;
  112. {
  113.     char buf[80];
  114.     char *bp;
  115.     int n, checksum, line;
  116.     int warnings = 5;
  117.  
  118.     for (line = 1; ; line++) {
  119.         /* for each input line */
  120.         if (fgets(buf, sizeof buf, in) == NULL) {
  121.             printf("Short file\n");
  122.             exit(10);
  123.         }
  124.  
  125.         checksum = 0;
  126.         n = DEC(buf[0]);
  127.         if (n <= 0)
  128.             break;
  129.  
  130.         bp = &buf[1];
  131.         while (n > 0) {
  132.             checksum = (checksum+outdec(bp, out, n)) % SUMSIZE;
  133.             bp += 4;
  134.             n -= 3;
  135.         }
  136.  
  137.         if (*bp != '\n' && checksum != DEC(*bp))
  138.             if (warnings > 0) {
  139.                 printf("Checksum error, line %d.\n",line);
  140.                 warnings--;
  141.             } else if (warnings == 0) {
  142.                 printf("more...\n");
  143.                 warnings--;
  144.             }
  145.     }
  146. }
  147.  
  148. /*
  149.  * output a group of 3 bytes (4 input characters).
  150.  * the input chars are pointed to by p, they are to
  151.  * be output to file f.  n is used to tell us not to
  152.  * output all of them at the end of the file.
  153.  * we return a checksum increment.
  154.  */
  155. int outdec(p, f, n)
  156. char *p;
  157. FILE *f;
  158. {
  159.     int c1, c2, c3;
  160.  
  161.     c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  162.     c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  163.     c3 = DEC(p[2]) << 6 | DEC(p[3]);
  164.  
  165.     if (n >= 1)
  166.         putc(c1, f);
  167.     if (n >= 2)
  168.         putc(c2, f);
  169.     if (n >= 3)
  170.         putc(c3, f);
  171.  
  172.     return((c1+c2+c3) % SUMSIZE);
  173. }
  174.  
  175.  
  176. /* fr: like read but stdio */
  177. int
  178. fr(fd, buf, cnt)
  179. FILE *fd;
  180. char *buf;
  181. int cnt;
  182. {
  183.     int c, i;
  184.  
  185.     for (i=0; i<cnt; i++) {
  186.         c = getc(fd);
  187.         if (c == EOF)
  188.             return(i);
  189.         buf[i] = c;
  190.     }
  191.     return (cnt);
  192. }
  193.  
  194. /*
  195.  * Return the ptr in sp at which the character c appears;
  196.  * NULL if not found
  197.  */
  198.  
  199. #ifndef NULL        /* MANX has bogus "#define NULL 0L" somewhere */
  200. #define    NULL    0
  201. #endif
  202.  
  203. char *
  204. index(sp, c)
  205. register char *sp, c;
  206. {
  207.     do {
  208.         if (*sp == c)
  209.             return(sp);
  210.     } while (*sp++);
  211.     return(NULL);
  212. }
  213.  
  214. #if (!unix && MANX)
  215.  
  216. perror (sp)
  217. char *sp;
  218. {
  219.     if (sp && *sp) {
  220.         fprintf (stderr, "%s: ");
  221.     }
  222.     fprintf (stderr, "<unknown error>\n");
  223. }
  224.  
  225. #endif    /* Unix */
  226.